<?php

/**
 * 通联协议支付
 * @author chenshubo
 */
namespace App\Service\VendorClient\AlinpayApi;

use App\Service\BaseService;
use App\Service\Code\Normal;

class AlinAgreePayApiClient extends BaseService
{ 
    private $config = [];
    public function __construct()
    {
        $this->config = config('api.alinagreepay');
    }
    
    /**
     * 协议支付签约短信触发(310001)
     * @param array $param
     * @return mixed
     */
    public function OrderPayBySendSmsCode( $param = [] )
    {
        $alinPayData = [
            'INFO'  => $this->getInfoParam($this->config['TRX_CODE']['SmsCode']),
            'FAGRA' => [
                'MERCHANT_ID'   => '122121',
                'ACCOUNT_TYPE'  => '00',
                'ACCOUNT_NO'    => '00000',
                'ACCOUNT_NAME'  => '111',
                'ACCOUNT_PROP'  => '0',
                'ID_TYPE'       => '0',
                'ID'            => '12313131313123',
                'TEL'           => '1522827236',
                'REMARK'        => '支付签约短信触发'
            ]
        ];
        $res = $this->getSign($this->getXml($alinPayData));
        if( $res['code'] != Normal::SUC ) {
            return $res;
        }
        
        $alinPayData['INFO']['SIGNED_MSG'] = $res['data'];
        $xml = $this->getXml($alinPayData);
        return $this->execute($xml);
    }
    
    /**
     * 获取xml
     * @param array $parameter
     */
    public function getXml( $parameter = [] ) 
    {
        $xmlTemp = [];
        foreach ($parameter as $key => $val ) {
            if( $key == 'INFO' ) {
                $xmlTemp[$key] = http::toArrayXml($val) . "\n";
            } else {
                $xmlTemp[$key] = http::toArrayXml($val);
            }
        }
        
        $xml = http::toArrayXml($xmlTemp);
        return http::toArrayXml(['AIPG'=>$xml]);
    }
    
    /**
     * 验证回调签名
     */
    public function checkSign( $param = [] )
    {
        $sign = $param['sign'];
        unset($param['sign']);
        ksort($param);
        $bufSignSrc = $this->ToUrlParams($param);
        $public_key = $this->config['public_key'];
        $public_key = chunk_split($public_key , 64, "\n");
        $key = "-----BEGIN PUBLIC KEY-----\n$public_key-----END PUBLIC KEY-----\n";
        $result= openssl_verify($bufSignSrc,base64_decode($sign), $key );
        return $result;
    }
    
    /**
     * 获取签名参数
     * @param array $param
     */
    protected function getSign( $xml = [] )
    {        
        //进行RSA签名
        $private_key = chunk_split($this->config['private_key'] , 64, "\n");
        $key = "-----BEGIN RSA PRIVATE KEY-----\n".wordwrap($private_key)."-----END RSA PRIVATE KEY-----";
        $signRes = openssl_sign($xml, $signature, $key );
        if( !$signRes ) {
            return Normal::returnCode(Normal::FAIL,"签名失败");
        }
        
        //加密后的内容通常含有特殊字符，需要编码转换下，在网络间通过url传输时要注意base64编码是否是url安全的
        return Normal::returnCode(Normal::SUC,"签名成功",base64_encode($signature));
    }
    
    /**
     * 获取交易码参数
     * @param $TRX_CODE
     */
    public function getInfoParam( $TRX_CODE = NULL ) 
    {
        return [
            'TRX_CODE'      => $TRX_CODE,
            'VERSION'       => $this->config['VERSION'],
            'DATA_TYPE'     => $this->config['DATA_TYPE'],
            'LEVEL'         => $this->config['LEVEL'],
            'MERCHANT_ID'   => $this->config['MERCHANT_ID'],
            'USER_NAME'     => $this->config['USER_NAME'],
            'USER_PASS'     => $this->config['USER_PASS'],
            'REQ_SN'        => DockeyId::instance()->getIncrementId()
        ];
    }
    
    /**
     * CURL请求
     * @param $params
     * @return mixed
     */
    public function execute( $xml = [] )  
    {
        $xml = '<?xml version="1.0" encoding="GBK"?>'.$xml;
        $applyUrl = $this->config['acount']['tradeUrl'];
        $header = [
            'Content-Type: application/xml'
        ];
        $start_time     = microtime(true);
        $res            = Http::apiRequest($applyUrl,$xml,'post',$header);
        $xml_reponse    = (array)simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
        $response       = isset($xml_reponse['INFO']) ? (array)$xml_reponse['INFO'] : [] ;
        $returnMsg      = [];
        if( isset($response['RET_CODE']) && $response['RET_CODE'] == '0000' ) {
            $returnMsg = Normal::returnCode(Normal::SUC,$response['ERR_MSG'],);
        } else if( isset($response['RET_CODE']) ) {
            $returnMsg = Normal::returnCode($response['RET_CODE'],$response['ERR_MSG']);
        } else {
            $returnMsg = Normal::returnCode(Normal::FAIL,"请求失败");
        }
        
        QueryGoodsMicService::instance()->addRequestLog([
            'interface_code'    => 'AlinAgreePay',
            'request_url'       => $applyUrl,
            'request_param'     => $xml,
            'response_code'     => $returnMsg['code'],
            'response_data'     => json_encode($response,JSON_UNESCAPED_UNICODE),
            'start_time'        => $start_time,
        ]);
        
        return $returnMsg;
    }
}